
module iTimer.ui.Task ;
import iTimer.Types ;
// import tango.io.FileSystem;
alias dwt.widgets.DateTime.DateTime DateTime;

private{
	static Color[3] gradientColors; 
	static int[2] percentArray = [10, 90];
    static Color[3]    tab_colors;
}


class iTaskList {
    
	struct MyCol {
		const char[]	title;
		const int		style;
		const int		width;
	}
	const MyCol[]	MyCols	= [
		{"ID", 	DWT.RIGHT, 30},
        
		{"类型",   DWT.LEFT,  40},
		{"时间", DWT.LEFT,  66},
		{"日期", DWT.LEFT,  126},
        
		{"文件", DWT.LEFT, 160},
		{"跳过秒数", DWT.RIGHT, 60},
		{"持续秒数",   DWT.LEFT,  60},
        
		{"有效", DWT.NONE,  40},
		 {" ", DWT.NONE,  30},
	];

	static Table Tab;
	static Menu menu;
    static Runnable async_update , async_stoped, async_started , async_paused, async_refresh , async_reload, async_playing ;
    static Atomic!(int) passed_time,  total_time; 

	static void load(Composite parent, FormData _layout_data){
        
        static class Reload_Runnable : Runnable {
            void run(){
                AppWin.bottom_msg_label.setText( "" );
                iTaskList.list(-1, true, true) ;
            }
        }
        async_reload   = new Reload_Runnable ;
        
        static class Refresh_Runnable : Runnable {
            void run(){
                AppWin.bottom_msg_label.setText( "" );
                iTaskList.list(-1) ;
            }
        }
        async_refresh   = new Refresh_Runnable ;
        
        static class Update_Runnable : Runnable {
            void run(){
                GShell.getDisplay().timerExec (10,  async_refresh ) ;
            }
        }
        async_update    = new Update_Runnable;
        
        static class Stoped_Runnable : Runnable {
            void run(){
                version(DEV) log!(__FILE__, __LINE__)("async_stoped");
                AppToolsBar.Play.setEnabled(true);
                AppToolsBar.Stop.setEnabled(false);
                GShell.getDisplay().timerExec (10 ,  async_refresh ) ;
                AppToolsBar.pos_enable(false);
            }
        }
        async_stoped    = new Stoped_Runnable;
        
        static class Started_Runnable : Runnable {
            void run(){
                version(DEV) log!(__FILE__, __LINE__)("async_started");
                AppToolsBar.Stop.setEnabled(true);
                GShell.getDisplay().timerExec (10 ,  async_refresh ) ;
                AppWin.bottom_msg_label.setText( "" );
                AppToolsBar.pos_enable(true,  0  ,  iTaskList.total_time.load() , true );
            }
        }
        async_started    = new Started_Runnable;
        
        static class Paused_Runnable : Runnable {
            void run(){
                version(DEV) log!(__FILE__, __LINE__)("async_paused");
                AppToolsBar.Play.setEnabled(true);
                AppToolsBar.Stop.setEnabled(false);
                GShell.getDisplay().timerExec (10 ,  async_refresh ) ;
            }
        }
        async_paused    = new Started_Runnable;
        
        static class Playing_Runnable : Runnable {
            void run(){
                AppToolsBar.pos_enable(true,  iTaskList.passed_time.load()  ,  iTaskList.total_time.load()  );
            }
        }
        async_playing   = new Playing_Runnable;
        
		gradientColors[0] = new Color( GShell.getDisplay().getDevice(), 0x99, 0x66, 0x00);
		gradientColors[1] = new Color( GShell.getDisplay().getDevice(), 0xff, 0xdd, 0xbb);
		gradientColors[2] = null;
        
        tab_colors[0]   = new Color( GShell.getDisplay().getDevice(), 0xaa, 0xaa, 0xaa);
		tab_colors[1]   =  new Color( GShell.getDisplay().getDevice(), 0x99, 0x66, 0x00);
		tab_colors[2]   = new Color( GShell.getDisplay().getDevice(), 0xff, 0x3, 0x3);
		
        /*
            Composite comp	= new Composite(parent, DWT.NONE );
            comp.setBackground(GShell.getDisplay().getSystemColor(DWT.COLOR_WHITE));
            comp.setLayoutData(_layout_data);
            comp.layout();
            comp.setLayout(new FillLayout() );
        */


		Tab = new Table (parent, DWT.TOP | DWT.BORDER | DWT.FULL_SELECTION | DWT.FLAT);  //  | DWT.CHECK  |  DWT.MULTI 
        Tab.setLayoutData(_layout_data);
		Tab.setLinesVisible (true);
		Tab.setHeaderVisible (true);
		
		foreach (ref col ; MyCols ) {
			auto column = new TableColumn (Tab, col.style );
			column.setText (col.title);
			if( col.width ) column.setWidth( col.width ); 
		}
         
		
		Tab.addSelectionListener(new class SelectionListener{
			public void widgetSelected(SelectionEvent e){
				int selected	= Tab.getSelectionIndex();
				Thread.sleep(.01);
				if( selected < 0 ){
                    AppMenus.Task_Menu_Items[1].setEnabled(false);
                    AppMenus.Task_Menu_Items[2].setEnabled(false);
                    AppToolsBar.Play.setEnabled(false);
				}else{
                    AppMenus.Task_Menu_Items[1].setEnabled(true);
                    AppMenus.Task_Menu_Items[2].setEnabled(true);
                    AppToolsBar.Play.setEnabled(true);
				}
			}
			public void widgetDefaultSelected(SelectionEvent e){}
		});
		
		CreateMenu ;
		list(-1, true) ;
        
	}
	
	static void list(int id = -1, bool reorder = false, bool is_auto_select  = true ) {
        version(DEV) log!(__FILE__, __LINE__)("task list id={},  reorder={} is_auto_select={}",  id, reorder , is_auto_select );
		if( id <= 0 ) {
			auto index	= Tab.getSelectionIndex();
			if( index >=0 ){
				id	= Int.parse(Tab.getItem( index ).getText(0) );
			}
		}
        
		int item_index	= -1 ;
        
        Item[]  item_list ;
        if( reorder ) {
		    Tab.removeAll ;
        } else {
            item_list   = Tab.getItems() ;
            if(  item_list.length !is Task_List.Length) {
                version(DEV) log!(__FILE__,__LINE__)("tab_len  = {},  task_len = {} ",  item_list.length , Task_List.Length);
            }
            // assert( );
        }
        ubyte[1024] tmp;
        scope bu  = new vBuffer(tmp);
        foreach(int i ,_vTask* p;  Task_List ) {
            scope file   = new FilePath(p.iFile) ;
            
            TableItem item ;
            if( reorder ) {
                item = new TableItem (Tab, DWT.NONE);
            } else {
                item = Tab.getItem(i) ;
            }
            
            auto cell_index  = 0 ;
            item.setText (cell_index++,  Int.toString(p.id) );
            
            if( p.isFire ) {
                // version(DEV) log!(__FILE__,__LINE__)("id= {},  isFire ", p.id );
                item.setForeground( tab_colors[2] );
            } else if( p.isDone ) {
                // version(DEV) log!(__FILE__,__LINE__)("id= {},  isDone ", p.id );
                item.setForeground( tab_colors[0] );
            } else if( p.isToday ) {
                // version(DEV) log!(__FILE__,__LINE__)("id= {},  isToday ", p.id );
                item.setForeground( tab_colors[1] );
            } else {
                // version(DEV) log!(__FILE__,__LINE__)("id= {},  else ", p.id );
                item.setForeground( tab_colors[0] );
            }
            
            if( p.iLoop ) {
                item.setText (cell_index++,  "每周"  );
                item.setText (cell_index++,  Task_List.iTime(p, bu)  );
                
                bu.clear;
                foreach(int i , _txt; iTask.WeekDays ) {
                    if( Task_List.hasDay(p, i) ){
                        bu(_txt)(' ');
                    }
                }
                item.setText (cell_index++,  cast(char[]) bu.slice );
                
            } else {
                item.setText (cell_index++,  "单日"  );
                item.setText (cell_index++,  Task_List.iTime(p, bu)  );
                item.setText (cell_index++,  Task_List.iDate(p, bu)  );
            }
            
            item.setText (cell_index++,  file.name );
            item.setText (cell_index++,  Int.toString(p.iSkip)  );
            item.setText (cell_index++,  Int.toString(p.iDuration)  );
            
            item.setText (cell_index++,  p.iUsed ?"否" : "是" );

             if( p.isFire ) {
                item.setText (cell_index++,  "*" );
            } else {
                item.setText (cell_index++, " " );
            }
            
            if( id is p.id ){
                item_index	= i ;
            }
        }
        
        // version(DEV) log!(__FILE__, __LINE__)("task list done" );
        
		if( is_auto_select && item_index >=0 ){
			Tab.select(item_index);
            AppMenus.Task_Menu_Items[1].setEnabled(true);
            AppMenus.Task_Menu_Items[2].setEnabled(true);
            AppToolsBar.Play.setEnabled(true);
		} else {
            AppMenus.Task_Menu_Items[1].setEnabled(false);
            AppMenus.Task_Menu_Items[2].setEnabled(false);
            AppToolsBar.Play.setEnabled(false);
        }
        
		foreach (int i, ref col ; MyCols ) {
			Tab.getColumn (i).setWidth( col.width ); 
		}
	}
	
    static void play_task(){
        int selected	= Tab.getSelectionIndex();
        if( selected >= 0 ) {
            auto item1	=  Tab.getItem(selected);
            int 	id	= Int.parse( item1.getText(0) );
            auto  p = Task_List.ByID( id) ;
            if(  p !is null ){
                if( !vPlayer.play( p.iFile, p.iSkip, p.iDuration, p.id )  ) {
                    AppWin.bottom_msg_label.setText( vPlayer.ip.ErrorMessage );
                }
            }
        }
    }
    static void stop_task(){
        //version(DEV) log1!(__FILE__,__LINE__)("stop_task");
        vPlayer.stop;
    }
    static void pause_task(){
        //version(DEV)  log1!(__FILE__,__LINE__)("pause_task");
        vPlayer.pause;
    }
    static void add_task(){
		iTask.Open;
    }
    
    static void edit_task(){
        int selected	= Tab.getSelectionIndex();
        if( selected >= 0 ){
            auto item1	=  Tab.getItem(selected);
            int 	id	= Int.parse( item1.getText(0) );
            iTask.Open( id );
        }
    }
    
    static void del_task(){
        int selected	= Tab.getSelectionIndex();
        if( selected >= 0 ){
            auto item1	=  Tab.getItem(selected);
            int 	id	= Int.parse( item1.getText(0) );
            try{
                int ret	= MessageBox.showMessageBox("确定要删除 `" ~ item1.getText(1) ~ "` 任务 `" ~  item1.getText(2) ~ "` 吗？", "提示", GShell, DWT.YES | DWT.NO  );
                if( ret == DWT.YES ){
                    Task_List.Delete(id);
                    // remove item 
                    list(-1, true) ;
                }
            }catch(Exception e){
                version(DEV)  log!(__FILE__, __LINE__)("throw: {}\n",  e.msg);
            }
        }
    }
    
	static void CreateMenu(){
		menu		= new Menu (GShell , DWT.POP_UP); 
		Tab.setMenu(menu);
		
		menu.addListener(DWT.Show, new class Listener{ 
			public void handleEvent (Event event) {
				int selected	= Tab.getSelectionIndex();
				//log2(__FILE__, __LINE__, "选择了: {}\n", selected);
				Thread.sleep(.01);
				if( selected < 0 ){
					menu.getItem(1).setEnabled(false);
					menu.getItem(2).setEnabled(false);
				}else{
					menu.getItem(1).setEnabled(true);
					menu.getItem(2).setEnabled(true);
				}
			} 
		}); 

		MenuItem addItem	= new MenuItem(menu, DWT.PUSH);
		addItem.setText("添加任务");
		addItem.addListener(DWT.Selection, new class Listener{ 
			public void handleEvent (Event event) { 
                add_task;
			}
		}); 
		
		MenuItem moItem	= new MenuItem(menu, DWT.PUSH);
		moItem.setText("修改任务");
		moItem.addListener(DWT.Selection, new class Listener{ 
			public void handleEvent (Event event) {
                edit_task;
			} 
		}); 
		
		MenuItem delItem	= new MenuItem(menu, DWT.PUSH);
		delItem.setText("删除任务");
		delItem.addListener(DWT.Selection, new class Listener{
			public void handleEvent (Event event) {
                del_task;
			}
		});
		
	}
	
}



class iTask {
    
	static const char[][] LoopTypes	= ["单日", "每周" ];
	static const char[][] WeekDays	= ["一", "二", "三", "四", "五", "六", "日" ];
	static const char[][] ISUSES	    = ["启用", "停用"];
	
    static shell_width  = 520 ;
    static shell_height = 400 ;
    static shell_space  = 3 ;
    static shell_element_height	= 32 ;
    static shell_element_top	= 8 ;
    static shell_element_left = 60 ;
    static shell_element_label_left = 10 ;
    
	static Shell 	    shell 			= null ;
    static Text         music_file     = null ;
    static Text         skip_text     = null ;
    static Text         duration_text     = null ;
	static CCombo	    is_used 	    = null ;
    static Button[]     loop_list, week_list ;
    static DateTime     date_time ;
    static DateTime    calendar ;
    static is_saved     = false ;
    
	static void Open( int id = -1 ){
		if( shell !is null){
            version(DEV) log!(__FILE__, __LINE__)("exists shell {:x} " , cast(void*) shell );
			shell.setActive();
			return ;
		}
        
        Task_List.Disable() ;

		shell		= new Shell (GShell , DWT.DIALOG_TRIM );
        version(DEV) log!(__FILE__, __LINE__)("create shell {:x} " , cast(void*) shell );
		
		shell.setText("添加任务");
		shell.addListener(DWT.Dispose, new class Listener{
			void handleEvent(Event e){
				iTask.shell	= null;
			}
		});
		
        win_task    = Task_List.ByID(id) ;
        if( win_task is null ) {
            win_task    = Task_List.New ;
        } else {
			shell.setText("修改任务");
        }
		addElements;
		// usr.setFocus;
		shell.setBounds(300, 300, shell_height , shell_width , 0);
        
        is_saved   = false ;
        shell.addListener(DWT.Dispose, new class() Listener {
            public void handleEvent(Event e) {
                version(DEV) log!(__FILE__, __LINE__)("disposed");
                doClear;
            }
        });
        
		shell.open();
	}
    
    static void doClear(){
        version(DEV) log!(__FILE__,__LINE__)("clear task_id = {}, vPlayer.getTaskId={}", (win_task is null )? -1 : win_task.id , vPlayer.getTaskId() );
        week_list   = [] ;
        loop_list   = [] ;
        win_task    = null ;
        music_file  = null ;
        skip_text   = null ;
        duration_text   = null ;
        date_time   = null ;
        calendar    = null ;
        Task_List.Enable() ;
        iTaskList.list(-1, is_saved) ;
        is_saved    = true ;
    }
    
    static Composite newEleemntComposite(int height, char[] label_text = null , bool child_comp = false ) {
        Composite comp = new Composite(shell,   DWT.NONE ) ;
		RowData fd	=	new RowData(shell_width, height ) ;
        
        comp.setLayoutData(fd);
        
        auto  layout  =  new FormLayout() ;
		comp.setLayout( layout ) ;
        
        if( label_text !is null ) {
            with( new Label(comp, DWT.NONE  ) ) {
                setBackground( GShell.getDisplay.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND ) );
                setText( label_text );
                FormData fd	=	new FormData();
                fd.top		=	new FormAttachment(0, shell_element_top + 2  );
                fd.left		=	new FormAttachment(0, shell_element_label_left );
                setLayoutData(fd);
            }
        }
        
        if( child_comp ) {
            Composite _comp = new Composite(comp,   DWT.NONE ) ;
            FormData fd	=	new FormData(shell_width - shell_element_left - shell_space  * 2  , height  - shell_space  * 2 ) ;
            fd.top		=	new FormAttachment(0, 0  );
            fd.left		=	new FormAttachment(0, shell_element_left );
            _comp.setLayoutData(fd) ;
            return _comp ;
        }
        
        return comp ;
    }
	
	static void addElements(){
        auto  shell_layout  =  new RowLayout() ;
        with( shell_layout ){
            pack    = true ;
            marginBottom    = 3 ;
            type   = DWT.VERTICAL ;
        }
		shell.setLayout( shell_layout ) ;
            
		Composite comp;
        int left_element    = 77 ;
        
        comp   = newEleemntComposite(shell_element_height, "频率" , true ) ;
        auto _layout    = new RowLayout() ;
        with(_layout) {
            spacing     = 8 ;
            marginTop   = shell_element_top ;
        }
		comp.setLayout( _layout ) ;
        
        static class onClick_Runnable : Runnable {
            void run(){
                version(DEV) log!(__FILE__,__LINE__)("iloop button click");
                if( loop_list[0].getSelection() ) {
                    calendar.setEnabled(true);
                    foreach(int i ,  ref btn ; week_list ) {
                        btn.setEnabled(false);
                    }
                } else {
                    calendar.setEnabled(false);
                    foreach(int i ,  ref btn ; week_list ) {
                        btn.setEnabled(true);
                    }
                }
            }
        }
        static Runnable loop_onclick   = null ;
        static class LoopListener : Listener {
            public void handleEvent (Event event) {
                GShell.getDisplay().timerExec( 10, loop_onclick);
            }
        }
        static Listener loop_listener   = null ;
        if( loop_listener is null ) {
            loop_listener    = new LoopListener();
            loop_onclick    = new onClick_Runnable();
        }
        foreach( int i , char[] radio_text; LoopTypes ) {
                Button btn  = new Button(comp, DWT.RADIO );
                loop_list  ~= btn ;
                with( btn ) {
                    setText( radio_text ) ;
                    if( i == win_task.iLoop) {
                        setSelection(true);
                    }
                    setBackground( GShell.getDisplay.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND ) );
		            RowData fd	=	new RowData() ;
                    setLayoutData(fd);
                }
                btn.addListener (DWT.Selection, loop_listener );
        }
        
        comp   = newEleemntComposite( 140, "日期" ) ;
        // comp.setBackground(GShell.getDisplay().getSystemColor(DWT.COLOR_RED));
        calendar = new DateTime (comp, DWT.CALENDAR);
        if( win_task.id > 0 && !win_task.iLoop  ) { 
            auto _iTime = win_task.iDate;
            calendar.setYear( _iTime / 10000 );
            _iTime  = _iTime % 10000 ;
            calendar.setMonth( _iTime /100 - 1 );
            _iTime  = _iTime % 100 ;
            calendar.setDay( _iTime  );
        }
        if( win_task.iLoop ) {
            calendar.setEnabled(false);
        }
        
		with( calendar ){
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
			setLayoutData(fd);
        }
        
        comp   = newEleemntComposite(shell_element_height, "日期" , true ) ;
        auto _layout2    = new RowLayout() ;
        with(_layout2) {
            spacing     = 2 ;
            marginTop   = shell_element_top ;
        }
		comp.setLayout( _layout2 ) ;
        foreach( int i , char[] radio_text; WeekDays ) {
                Button btn  = new Button(comp, DWT.CHECK );
                week_list  ~= btn ;
                with( btn ) {
                    setText( radio_text ) ;
                    if( Task_List.hasDay(win_task, i) ){
                        setSelection(true);
                    }
                    setBackground( GShell.getDisplay.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND ) );
		            RowData fd	=	new RowData() ;
                    setLayoutData(fd);
                }
        }
        if( !win_task.iLoop ) {
            foreach(int i ,  ref btn ; week_list ) {
                btn.setEnabled(false);
            }
        }
        
        comp   = newEleemntComposite( shell_element_height, "时钟" ) ;
        date_time = new DateTime (comp, DWT.TIME);
        
        auto _iTime = win_task.iTime  ;
        if( win_task.id > 0 ) { 
            date_time.setHours( _iTime / 10000 );
        } else {
            date_time.setHours( 8 );
        }
        _iTime  = _iTime % 10000 ;
        date_time.setMinutes( _iTime /100  );
        _iTime  = _iTime % 100 ;
        date_time.setSeconds( _iTime  );
        
        
		with( date_time ){
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
			setLayoutData(fd);
        }
        
        auto element_width  = 160 ;
        comp   = newEleemntComposite( shell_element_height, "文件" ) ;
        music_file = new Text(comp, DWT.BORDER) ;
		with( music_file ){
            setText( win_task.iFile );
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
            fd.width   = element_width ;
			setLayoutData(fd);
        }
		auto pick_file		= new Button(comp, DWT.PUSH);
		with( pick_file ){
			setText( "浏览" );
            FormData fd	=	new FormData();
            fd.top		=	new FormAttachment(0, shell_element_top - 2  );
            fd.left		=	new FormAttachment(0, shell_element_left + element_width + 10 );
            setLayoutData(fd);
        }
		pick_file.addListener(DWT.MouseUp, dgListener(&onChangeFile));
		auto try_play		= new Button(comp, DWT.PUSH);
		with( try_play ){
			setText( "试听" );
            FormData fd	=	new FormData();
            fd.top		=	new FormAttachment(0, shell_element_top - 2  );
            fd.left		=	new FormAttachment(0, shell_element_left + element_width + 50 );
            setLayoutData(fd);
        }
		try_play.addListener(DWT.MouseUp, dgListener(&onTryPlay));
        
        comp   = newEleemntComposite( shell_element_height, "跳过" ) ;
        skip_text = new Text(comp, DWT.BORDER) ;

		with( skip_text ){
            setText(  Int.toString(win_task.iSkip) );
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
            fd.width   = 23 ;
			setLayoutData(fd);
        }
        with( new Label(comp, DWT.NONE  ) ) {
            setBackground( GShell.getDisplay.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND ) );
            setText( "秒" );
            FormData fd	=	new FormData();
            fd.top		=	new FormAttachment(0, shell_element_top + 2  );
            fd.left		=	new FormAttachment(0, shell_element_left + 36 );
            setLayoutData(fd);
        }
        
        comp   = newEleemntComposite( shell_element_height, "持续" ) ;
        duration_text = new Text(comp, DWT.BORDER) ;
		with( duration_text ){
            setText( Int.toString(win_task.iDuration) );
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
            fd.width   = 23 ;
			setLayoutData(fd);
        }
        with( new Label(comp, DWT.NONE  ) ) {
            setBackground( GShell.getDisplay.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND ) );
            setText( "秒" );
            FormData fd	=	new FormData();
            fd.top		=	new FormAttachment(0, shell_element_top + 2  );
            fd.left		=	new FormAttachment(0, shell_element_left + 36 );
            setLayoutData(fd);
        }
        
        comp   = newEleemntComposite( shell_element_height, "状态" ) ;
		is_used	= new CCombo(comp, DWT.FLAT | DWT.BORDER | DWT.READ_ONLY );
		with( is_used ){
			FormData fd	=	new FormData();
			fd.top		=	new FormAttachment(0, shell_element_top );
			fd.left		=	new FormAttachment(0,  shell_element_left );
			fd.width		=	46;
			setLayoutData(fd);
            foreach(text; ISUSES){
			    add(text);
            }
			select(win_task. iUsed );
		}
        
        
        comp   = newEleemntComposite( 60,  null ) ;
        // comp.setBackground(GShell.getDisplay().getSystemColor(DWT.COLOR_RED));
        
		auto submit		= new Button(comp, DWT.PUSH);
		auto cancel		= new Button(comp, DWT.PUSH);
		
		with(submit){
			setText("确认");
			FormData fd	=	new FormData();
			fd.bottom		=	new FormAttachment(90, -10 );
			fd.left		=	new FormAttachment(50, 10 );
			setLayoutData(fd);
		}
		with( cancel ){
			setText( "取消" );
			FormData fd	=	new FormData();
			fd.bottom		=	new FormAttachment(90, -10 );
			fd.left		=	new FormAttachment(50, 60 );
			setLayoutData(fd);
		}
		
		submit.addListener(DWT.MouseUp, dgListener(&onSubmit));
		cancel.addListener(DWT.MouseUp, dgListener(&onCancel));
        
        static void only_number(Text text){
            text.addVerifyListener(new class() VerifyListener {   
                   public void verifyText(VerifyEvent e) {   
                        foreach( int i, c ; e.text){
                            if( c < '0' || c > '9' ) {
                                e.doit  = false ;
                                return  ;
                            }
                        }
                        e.doit  = true ;
                   }
           });
        }
        only_number(skip_text);
        only_number(duration_text);
        return ;
        
	}
	
	static void onChangeFile(Event e){
        scope dialog = new FileDialog (shell);
        // dialog.setFilterPath (FileSystem.getDirectory());
        dialog.setFilterExtensions(["*.mp3", "*.wma", "*.ape"]);
        auto file   = dialog.open() ;
        music_file.setText(file);
        dialog.dispose;
    }
	static void onTryPlay(Event e) {
        auto file   = music_file.getText() ;
        if( !Pth.exists(file) ) {
            MessageBox.showInfo("文件不存在！" );
            return;
        }
        try{
            if( ! vPlayer.play(file, Int.toInt( skip_text.getText() ) , Int.toInt( duration_text.getText() ), win_task.id ) ) {
                AppWin.bottom_msg_label.setText( vPlayer.ip.ErrorMessage );
            }
        }catch(Exception e){
            version(DEV)  log!(__FILE__, __LINE__)("try play throw : {} ", e );
        }
    }
    
	static void onSubmit(Event e){
        
        static void setValueByText(char[] text, in char[][] list,  ref uint index){
            foreach(int i, ref _text; list){
                if( text == _text ){
                    index   = i ;
                }
            }
        }
        
        // version(DEV) log!(__FILE__,__LINE__)("get music_file");
        auto file   = music_file.getText() ;
        if( !Pth.exists(file) ) {
            MessageBox.showInfo("文件不存在！" );
            return;
        }
        win_task.iFile  = file ;
        
        // version(DEV) log!(__FILE__,__LINE__)("get loop_list ,  len={}", loop_list.length);
        foreach( int i, btn; loop_list){
            if( btn.getSelection() ){
                win_task.iLoop  = i ;
            }
        }
        
        // version(DEV) log!(__FILE__,__LINE__)("get week_list ,  len={}", week_list.length);
        win_task.iDays    =  0 ; 
        foreach( int i, btn; week_list){
            if( btn.getSelection() ){
                Task_List.setDay(win_task, i);
            }
        }
        
        // version(DEV) log!(__FILE__,__LINE__)("get is_used");
        setValueByText(is_used.getText(), ISUSES , win_task.iUsed);
        
        // version(DEV) log!(__FILE__,__LINE__)("get skip_text");
        win_task.iSkip = Int.toInt( skip_text.getText() ) ;
        
        // version(DEV) log!(__FILE__,__LINE__)("get duration_text");
        win_task.iDuration  = Int.toInt( duration_text.getText() ) ;
        
        // version(DEV) log!(__FILE__,__LINE__)("get calendar");
        win_task.iDate  = calendar.getYear () * 10000 + ( calendar.getMonth () +1 ) * 100 +calendar.getDay () ;
        
        // version(DEV) log!(__FILE__,__LINE__)("get date_time");
        win_task.iTime  = date_time.getHours() * 10000 + date_time.getMinutes() * 100 + date_time.getSeconds() ;
    
        // version(DEV) log!(__FILE__,__LINE__)("before save item");
        // save
        Task_List.Save(win_task) ;
        is_saved    = true ;
        // version(DEV) log!(__FILE__,__LINE__)("try dispose");
        shell.dispose;
	}
	static void onCancel(Event e){
		shell.dispose;
	}
}